package top.pengdong.pictureShare.tweet.handle;

import lombok.extern.slf4j.Slf4j;
import org.omg.CORBA.PRIVATE_MEMBER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import top.pengdong.pictureShare.tweet.entity.PsTweetEntity;
import top.pengdong.pictureShare.tweet.service.PsTweetService;
import top.pengdong.pictureShare.tweet.utils.RedisUtil;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
/**
 * @desc 定时任务 进行 每隔15分钟进行数据写入到数据库上，主要是用户点赞浏览的记录
 * 这部分内容还是很有难度的，现在设计调库操作进行设计
 * @param
 * @return
 * @author pengshi
 * @date 2022/5/1 11:05
 **/
@Slf4j
//@Component
//@Order(Ordered.HIGHEST_PRECEDENCE)
public class ListenHandler {

    private final PsTweetService psTweetService;
    private final RedisUtil redisUtil;

    public static final String VIEW_KEY = "COUNT_TWEET:viewNum";
    public static final String COMMENT_KEY = "COUNT_TWEET:commentNum";
    public static final String LIKE_KEY = "COUNT_TWEET:likeNum";
    public static final String FORWARD_KEY = "COUNT_TWEET:forwardNum";
    public static final String COLLECTION_KEY = "COUNT_TWEET:collectionNum";

    // 统计记录总值
    public Map<String, Integer> CountSum = new HashMap<>();
 
    @Autowired
    public ListenHandler(PsTweetService psTweetService, RedisUtil redisUtil) {
        this.psTweetService = psTweetService;
        this.redisUtil = redisUtil;
    }
 
    @PostConstruct
    public void init() throws Exception {
        log.info("统计数据初始化开始...");
        //将数据库中的数据写入redis
        List<PsTweetEntity> psTweetEntities = psTweetService.list();
        psTweetEntities.forEach(psTweet -> {
            //将浏览量、点赞数和评论数写入redis
            cacheAddNewTweet(psTweet);
        });
        log.info("统计数据已写入redis...");
    }

    /**
     * 添加文章的点赞数量 设置
     */
    public void cacheAddNewTweet(PsTweetEntity psTweet) {
        redisUtil.zAdd(VIEW_KEY, psTweet.getId().toString(), psTweet.getViewCount());
        redisUtil.zAdd(COMMENT_KEY, psTweet.getId().toString(), psTweet.getCommentCount());
        redisUtil.zAdd(LIKE_KEY, psTweet.getId().toString(), psTweet.getLikeCount());
        redisUtil.zAdd(FORWARD_KEY, psTweet.getId().toString(), psTweet.getForwardCount());
        redisUtil.zAdd(COLLECTION_KEY, psTweet.getId().toString(), psTweet.getCollectionCount());
    }

    /**
     * 关闭时操作
     */
    @PreDestroy
    public void afterDestroy() {
        log.info("开始关闭...");
        writeData();
        log.info("redis写入数据库完毕");
    }
 
    @Scheduled(cron = "0 0 0 * * ?")
    public void updateNum() {
        log.info("周期任务开始执行...");
        writeData();
        log.info("周期任务执行完毕,redis写入数据库完毕");
    }

    /**
     * 这里刷入数据是前10的数据
     */
    private void writeData() {
        //将redis中的数据写入数据库
        Set<ZSetOperations.TypedTuple<String>> viewNum = redisUtil.zReverseRangeWithScores(VIEW_KEY, 0, 10);
        Set<ZSetOperations.TypedTuple<String>> commentNum = redisUtil.zReverseRangeWithScores(COMMENT_KEY, 0, 10);
        Set<ZSetOperations.TypedTuple<String>> likeNum = redisUtil.zReverseRangeWithScores(LIKE_KEY, 0, 10);
        Set<ZSetOperations.TypedTuple<String>> forwardNum = redisUtil.zReverseRangeWithScores(FORWARD_KEY, 0, 10);
        Set<ZSetOperations.TypedTuple<String>> collectionNum = redisUtil.zReverseRangeWithScores(COLLECTION_KEY, 0, 10);
        writeNum(viewNum, VIEW_KEY);
        writeNum(commentNum, COMMENT_KEY);
        writeNum(likeNum, LIKE_KEY);
        writeNum(forwardNum, FORWARD_KEY);
        writeNum(collectionNum, COLLECTION_KEY);
    }
 
    private void writeNum(Set<ZSetOperations.TypedTuple<String>> set, String fieldName) {
        set.forEach(item -> {
            Long id = Long.valueOf(item.getValue());
            Integer num = item.getScore().intValue();
 
            PsTweetEntity psTweet = psTweetService.getById(id);
            switch (fieldName) {
                case VIEW_KEY:
                    psTweet.setViewCount(num);
                    break;
                case COMMENT_KEY:
                    psTweet.setCommentCount(num);
                    break;
                case LIKE_KEY:
                    psTweet.setLikeCount(num);
                    break;
                case FORWARD_KEY:
                    psTweet.setForwardCount(num);
                    break;
                case COLLECTION_KEY:
                    psTweet.setCollectionCount(num);
                    break;
                default:
                    return;
            }
 
            //更新数据库
            psTweetService.updateNumById(psTweet);
            log.info("{} 更新完毕", fieldName);
        });
    }

}